Python + Shell 巡检服务器

您所在的位置:网站首页 python 巡检数据库服务器 Python + Shell 巡检服务器

Python + Shell 巡检服务器

2024-05-31 03:09| 来源: 网络整理| 查看: 265

1. 背景

团队维护多套业务系统,有支付系统、金融系统、数据系统、核验系统等二十多套业务系统,每套业务系统有10 - 50台服务器不等,当前团队中存在一套自动化巡检系统,每十分钟巡检一次,有异常可实时告警。但每天还需要人工登录服务器巡检两次,因人工巡检耗时长、漏巡风险大,需要一个运维巡检工具帮助实现快速人工巡检。

2. 巡检逻辑

3. 功能实现

通过巡检机的python脚本登录各系统服务器并执行存在的shell巡检脚本,获取shell脚本产生的巡检结果并处理,最终生成Excel文件。

3.1 shell部分

先部署基础的shell巡检脚本,脚本需要实现即时显示各巡检项状态、输出巡检日志和反馈给python处理的巡检结果文件

#!/bin/bash # 全系统统一巡检脚本 # ↓ ↓ ↓ 写在脚本开头 ↓ ↓ ↓ # # global variables log_dir=/tmp/unity/unitylog # 日志路径 exe_dir=/tmp/unity # 执行路径 clean_size=200 # 日志清理大小 # create log directory if [ ! -d $log_dir ];then mkdir -p $log_dir else # clean log # clean up when log file is greater than $clean_size. log_size=`du -sm $log_dir/unity_patrol.log | awk '{print $1}'` if [ $log_size -ge $clean_size ];then echo > $log_dir/unity_patrol.log fi fi echo "[$(date "+%Y-%m-%d %H:%M:%S")] [INFO] [SYSTEM] Start System Patrol." >> $log_dir/unity_patrol.log # create a title cat $exe_dir/unity_patrol.sh | grep "item_name=" | grep -v "grep" | awk -F"=" '{print $2}' | awk '{print $1}' | tr '\n' ',' | awk '{print $0}' > $log_dir/unity_patrol.txt # ↑ ↑ ↑ 写在脚本开头 ↑ ↑ ↑ # # HA状态 item_name=HA_STATUS # 巡检项 alarm_value="ST_STABLE" # 告警值 echo "[$(date "+%Y-%m-%d %H:%M:%S")] [INFO] [$item_name] START" >> $log_dir/unity_patrol.log echo "[$(date "+%Y-%m-%d %H:%M:%S")] [INFO] [$item_name] get hacmp status." >> $log_dir/unity_patrol.log lssrc -ls clstrmgrES >> $log_dir/unity_patrol.log hacmp_status=`lssrc -ls clstrmgrES | grep "Current state" | awk -F":" '{print $2}' | awk '{print $1}'` if [ "$hacmp_status" == "$alarm_value" ];then echo "[$(date "+%Y-%m-%d %H:%M:%S")] [INFO] [$item_name] hacmp status is $subsystem_status." >> $log_dir/unity_patrol.log echo "hacmp status:$hacmp_status" >> $log_dir/unity_patrol.tmp echo "[$item_name] hacmp status: $hacmp_status ==> OK" else echo "[$(date "+%Y-%m-%d %H:%M:%S")] [ERROR] [$item_name] hacmp status is $subsystem_status." >> $log_dir/unity_patrol.log echo "hacmp status:$hacmp_status*" >> $log_dir/unity_patrol.tmp echo "[$item_name] hacmp status: $hacmp_status ==> Failed" echo "[$item_name] lssrc -ls clstrmgrES" fi echo "[$(date "+%Y-%m-%d %H:%M:%S")] [INFO] [$item_name] END" >> $log_dir/unity_patrol.log # 磁盘监控 ... # 内存监控 ... # cpu监控 ... # xxx服务监控 ... # ↓ ↓ ↓ 写在脚本结尾 ↓ ↓ ↓ # # global variables log_dir=/tmp/unity/unitylog # 日志路径 # process all inspection data cat $log_dir/unity_patrol.tmp | tr '\n' ',' | awk '{print $0}' >> $log_dir/unity_patrol.txt rm -rf $log_dir/*.tmp echo "[$(date "+%Y-%m-%d %H:%M:%S")] [INFO] [SYSTEM] the system patrol has been completed." >> $log_dir/unity_patrol.log # ↑ ↑ ↑ 写在脚本结尾 ↑ ↑ ↑ #

写在脚本开头

目录不存在时自动创建目录巡检输出的日志超过200M时自动清理获取脚本中所有巡检项

写在脚本结尾

处理给python输出的巡检结果文件,每个巡检项之间用逗号分隔清理临时文件 3.2 Python部分

3.2.1 定义全局变量

Python部分使用paramiko库连接服务器,并执行服务器的shell脚本,因考虑到密码安全性,我们把服务器登录密码加密后写入mysql数据库,登录时从数据库中获取加密密码,解密后再登录服务器。

import os import re import sys import time import email from email.mime.multipart import MIMEMultipart from email.mime.text import MIMEText from email.mime.application import MIMEApplication import smtplib import imaplib import pymysql import binascii from pyDes import des, CBC, PAD_PKCS5 import paramiko import pandas as pd import openpyxl from openpyxl.styles.borders import Border, Side from openpyxl.utils import get_column_letter from openpyxl.styles import PatternFill class Encrypt: # 全局变量 def __init__(self): # 配置加密key self.key = '12345678' self.iv = self.key # 配置数据库连接和服务器登录信息 self.conn = pymysql.connect(host='192.168.x.x', user='admin', password='xxxxxx', database='xxDB', port=3306) self.cursor = self.conn.cursor() self.cursor_getservers = self.conn.cursor() self.ssh = paramiko.SSHClient() self.ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) # 获取业务系统IP self.systems = self.get_servers() self.title_list = ['IP', 'SERVER_TYPE'] # 设置Excel文件导出位置 self.export_excel = "C:\\Users\\user\\Desktop\\export\\export_excel.xlsx" self.xlsx_file_name = pd.ExcelWriter(self.export_excel) # 密码加密 def des_encrypt(self, txt): k = des(self.key, CBC, self.iv, pad=None, padmode=PAD_PKCS5) en = k.encrypt(txt, padmode=PAD_PKCS5) return binascii.b2a_hex(en) # 密码解密 def des_decrypt(self, txt): k = des(self.key, CBC, self.iv, pad=None, padmode=PAD_PKCS5) de = k.decrypt(binascii.a2b_hex(txt), padmode=PAD_PKCS5) return de # 获取各系统登录数据 def get_serverinfo(self, system): select_systeminfo = 'select system, ip, server_type, user, passwd from tbl_systeminfo where system = \'{}\''.format(system) self.cursor.execute(select_systeminfo) return self.cursor.fetchall() # 获取所有系统名 def get_servers(self): select_systems = 'select system from tbl_systeminfo group by system' self.cursor_getservers.execute(select_systems) systems_list = [] for system in self.cursor_getservers.fetchall(): systems_list.append(system[0]) return systems_list

3.2.2 远程执行shell脚本

登录服务器后执行shell脚本,运行后续函数的时候发现一个问题,有些服务器没有部署shell脚本,就会导致程序报错断开,因为后面会用到exp_info变量,变量为空时无法处理数据,所以在执行shell脚本是做了一个是否存在脚本的判断,或者在之后的函数中增加变量是否为空的判断,我选择判断脚本,因为在调试的时候会比较直观。

# 登录并执行shell脚本 def login_exec_sh(self, host, username, password): try: self.ssh.connect(hostname=host, username=username, password=password, timeout=5) stdin, stdout, stderr = self.ssh.exec_command('[ -f /tmp/monitx/unity_patrol.sh ] && sh /tmp/monitx/unity_patrol.sh || echo "SSH_ERROR"') stdout_content = stdout.read().decode('utf-8') if 'SSH_ERROR' in stdout_content: exp_info = 'SSH_ERROR' else: stdin1, stdout1, stderr1 = self.ssh.exec_command('cat /tmp/monitx/unitylog/unity_patrol.txt') exp_info = stdout1.read().decode('utf-8') except Exception as e: print(e) exp_info = 'SSH_ERROR' return exp_info

3.2.3 处理脚本执行结果

所有系统巡检一次需要几十分钟,可以在周末或节假日的时候使用,平时各系统工程师可以通过指定系统进行巡检。 使用pandas库将巡检结果导出到Excel文件中,为避免所有系统信息暴漏,导出的IP地址做了脱敏处理;无法连通的地址或者无巡检脚本的地址都会标星*,shell脚本输出的巡检结果中异常巡检项也会做标星*处理。

# 数据处理 def run(self): # 判断是否为全系统巡检 # 若需要巡检部分系统输入巡检的系统名称,否则为全系统巡检 print("""请输入要巡检的系统名称,以空格为分隔符 不输入为全系统巡检 """) xj_system = input("输入要巡检的系统: ").splitlines() xj_system = "".join(xj_system).split(' ') print(""" --> 开始全系统巡检 巡 检 结 束


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3